import {GameLoading} from "./managers/LoadingManager";
import {AlertParam, GameError, GameModal, GameToast, IconType} from "./managers/AlertManager";
import {Interface, InterfaceLoading, InterfaceOptions, Method, networkMgr} from "./managers/NetworkManager";

export function toast(title: string,
											icon: IconType = "none",
											mask: boolean = false) {
	return (obj, key, desc) => {
		desc.value = () =>
			new GameToast({title, icon, mask})
	}
}
export function modal(title: string, content?: string,
											showCancel: boolean = false,
											editable: boolean = false) {
	return (obj, key, desc) => {
		desc.value = (_content?: string) =>
			new GameModal({
				title, content: _content || content,
				showCancel, editable
			})
	}
}

export function loading(code: number, title: string, mask: boolean = false) {
	return (obj, key, desc) => {
		desc.value = () => new GameLoading(code, title, mask);
	}
}

export function error(code: number, errMsg: string,
											alert?: AlertParam) {
	return (obj, key, desc) => {
		desc.value = (detail, data) => {
			throw new GameError(code, errMsg,
				alert, detail, data);
		};
	}
}

export function post(
	p1: string, p2?: string | InterfaceLoading,
	p3?: InterfaceLoading | boolean, p4?: boolean) {

	const opt = makeInterfaceOption("POST", p1, p2, p3, p4);

	return (obj, key, desc) => {
		desc.value = p => networkMgr().request(new Interface(opt), p)
	}
}
export function get(
	p1: string, p2?: string | InterfaceLoading,
	p3?: InterfaceLoading | boolean, p4?: boolean) {

	const opt = makeInterfaceOption("GET", p1, p2, p3, p4);

	return (obj, key, desc) => {
		desc.value = d => networkMgr().request(new Interface(opt), d)
	}
}

function makeInterfaceOption(method: Method,
														 hostOrRoute: string,
														 routeOrLoading?: string | InterfaceLoading,
														 loadingOrUseToken?: InterfaceLoading | boolean,
														 useEncrypt: boolean = true): InterfaceOptions {
	const res: InterfaceOptions = { method, route: hostOrRoute };
	if (typeof routeOrLoading === "string") { // 有host参数
		res.host = hostOrRoute;
		res.route = routeOrLoading;
		res.loading = loadingOrUseToken;
		// 有host参数，不可设置token和加密
		res.useToken = res.useEncrypt = false;
	} else {
		res.loading = routeOrLoading;
		// @ts-ignore
		res.useToken = loadingOrUseToken;
		res.useEncrypt = useEncrypt;
	}
	if (res.useToken === undefined) res.useToken = true;
	return res;
}

// export function post(route: string, loading?: InterfaceLoading,
// 										 useToken: boolean = true) {
// 	return (obj, key, desc) => {
// 		desc.value = () => new Post({
// 			route, loading, useToken
// 		})
// 	}
// }
// export function get(route: string, loading?: InterfaceLoading,
// 										 useToken: boolean = true) {
// 	return (obj, key, desc) => {
// 		desc.value = () => new Get({
// 			route, loading, useToken
// 		})
// 	}
// }

export class CoreAlert {

	@toast("发生错误", "error") static DefaultError(...p): any {}
}

export class CoreThrow {

	@error(100000, "系统错误", CoreAlert.DefaultError) static SystemError(...p) {}

}

export class CoreLoading {

	@loading(100000, "加载中") static Default(...p): any {};
	@loading(100001, "加载中", true) static Mask(...p): any {};
	@loading(100002, "加载中") static Request(...p): any {};
	@loading(100003, "上传中") static Upload(...p): any {};

}

export class CoreInterface {
	@get("/core/data/get", undefined, false)
	static GetData(d?): any {}

	@post("/core/token/update", false)
	static UpdateToken(d?): any {};
}

